package com.monkeysonnet.b2dFluent;

import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.BodyDef;
import com.badlogic.gdx.physics.box2d.BodyDef.BodyType;
import com.badlogic.gdx.physics.box2d.World;
import com.badlogic.gdx.utils.Array;

public class BodyFactory
{
	private static final BodyDef _initialDef = new BodyDef();
	
	private BodyDef _def;
	private Array<FixtureFactory<?>> _fixtures;
	private Object _userData;
	private boolean _managed;
	
	public BodyFactory()
	{
		this(false);
	}
	
	BodyFactory(boolean managed)
	{
		_managed = managed;
		_def = new BodyDef();
		_fixtures = new Array<FixtureFactory<?>>();		
	}
	
	void clear()
	{
		_def.active = _initialDef.active;
		_def.allowSleep = _initialDef.allowSleep;
		_def.angle = _initialDef.angle;
		_def.angularDamping = _initialDef.angularDamping;
		_def.angularVelocity = _initialDef.angularVelocity;
		_def.awake = _initialDef.awake;
		_def.bullet = _initialDef.bullet;
		_def.fixedRotation = _initialDef.fixedRotation;
		_def.gravityScale = _initialDef.gravityScale;
		_def.linearDamping = _initialDef.linearDamping;
		_def.linearVelocity.set(_initialDef.linearVelocity);
		_def.position.set(_initialDef.position);
		_def.type = _initialDef.type;
		
		_userData = null;
		_fixtures.clear();
	}
	
	public Body create(World world)
	{
		Body b = world.createBody(_def);
		b.setUserData(_userData);
		for(FixtureFactory<?> f : _fixtures)
			f.create(b);
				
		if(_managed)
			B2d.free(this);
				
		return b;
	}
	
	public BodyFactory type(BodyType t)
	{
		_def.type = t;
		return this;
	}
	
	public BodyFactory at(float x, float y)
	{
		_def.position.set(x, y);
		return this;
	}	
	
	public BodyFactory at(Vector2 v)
	{
		_def.position.set(v);
		return this;
	}	
	
	public BodyFactory rotated(float a)
	{
		_def.angle = a;
		return this;
	}	
	
	public BodyFactory angularVelocity(float v)
	{
		_def.angularVelocity = v;
		return this;
	}	
	
	public BodyFactory active(boolean a)
	{
		_def.active = a;
		return this;
	}	
	
	public BodyFactory awake(boolean a)
	{
		_def.awake = a;
		return this;
	}	
	
	public BodyFactory allowSleep(boolean a)
	{
		_def.allowSleep = a;
		return this;
	}	
	
	public BodyFactory bullet(boolean b)
	{
		_def.bullet = b;
		return this;
	}	
	
	public BodyFactory fixedRotation(boolean f)
	{
		_def.fixedRotation = f;
		return this;
	}
	
	public BodyFactory gravityScale(float s)
	{
		_def.gravityScale = s;
		return this;
	}	
	
	public BodyFactory linearDamping(float d)
	{
		_def.linearDamping = d;
		return this;
	}	
	
	public BodyFactory linearVelocity(Vector2 v)
	{
		_def.linearVelocity.set(v);
		return this;
	}	
	
	public BodyFactory withFixture(FixtureFactory<?> f)
	{
		_fixtures.add(f);
		return this;
	}
	
	public BodyFactory userData(Object d)
	{
		_userData = d;
		return this;
	}
	
	public BodyFactory angularDamping(float d)
	{
		_def.angularDamping = d;
		return this;
	}
}
